<template>
	<view class='classify' :style="{ 'height': height == 0 ? windowHeight + 'px' : height + 'rpx' }">
		<view class="left-main">
			<scroll-view scroll-y style="height: 100%;" :show-scrollbar="false" :scroll-with-animation="true"
				:scroll-into-view="goodsIntoView">
				<view @click="onSelectClassify(index)" class="class-item" v-for="(item, index) in classifyList"
					:key="index" :id="'classItem' + index"
					:class="{ 'class-item-active': currentLeftClassify === index }">{{ item.typeName }}</view>
			</scroll-view>
		</view>
		<view class="right-main">
			<!-- 二级分类 -->
			<!-- <view class="child-class-main">
				<scroll-view scroll-x style="white-space: nowrap;" :show-scrollbar="false" :scroll-with-animation="true"
					:scroll-into-view="childClassIntoView">
					<view class="child-class-box">
						<view @click="onChildSelectClassify(index)" class="child-class-item"
							:id="'childClassItem' + index" v-for="(item, index) in currentChildClassList" :key="index"
							:class="{ 'child-class-item-active': currentChildClassify === index }">
							{{ item.name }}
						</view>
					</view>
				</scroll-view>
			</view> -->

			<!-- 商品列表  -->
			<view class="goods-list">
				<scroll-view scroll-y style="height: 100%;" class="content-scroll" :scroll-top="scrollTop"
					:show-scrollbar="false" :scroll-with-animation="true" upper-threshold="10" lower-threshold="10"
					:scroll-into-view="goodsIntoView" @scroll="onScroll" @scrolltoupper="onScrollToUpper"
					@scrolltolower="onScrollToLower">
					<view class="child-item" :id="'goodsItem' + index" v-for="(item, index) in classifyList"
						:key="index"
						:style="{ 'height': index === classifyList.length - 1 ? goodsListHeight + 'px' : 'auto' }">
						<view class="title">{{ item.typeName }}</view>
						<view @click="onClickGoods(goods, goodsIndex)" class="goods-item"
							v-for="(goods, goodsIndex) in item.productList" :key="goodsIndex">
							<image class="goods-img" :src="goods.image" />
							<view class="goods-name">{{ goods.name }}</view>
						</view>
					</view>
					<!-- 加载提示 -->
					<view class="loading-tip" v-if="isLoading">
						<text>切换下一个分类..</text>
					</view>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			classifyList: { // 分类列表
				type: Array,
				default () {
					return []
				}
			},
			height: { // 组件高度
				type: Number,
				default () {
					return 0
				}
			}
		},
		data() {
			return {
				windowHeight: 0,
				currentLeftClassify: 0, // 当前选中的左侧分类索引
				classIntoView: 'classItem0', // 滚动到指定一级分类标签
				currentChildClassify: 0, // 当前选中的右侧二级分类索引
				childClassIntoView: 'childClassItem0', // 滚动到指定二级分类标签
				goodsIntoView: 'goodsItem0', // 滚动到指定商品列表
				goodsListHeight: 0, // 商品列表高度
				itemPositions: [], // 每个内容块的位置信息
				isCalculating: false, // 是否正在滚动
				checkClassTimer: null, // 防抖定时器
				scrollTimer: null,
				targetScrollTop: 0, // 目标滚动位置
				threshold: 20, // 滚动阈值，距离顶部多少像素时切换分类
				scrollTop: 0, // 滚动位置
				saveScrollTop: 0, // 保存滚动位置
				oldScrollTop: 0, // 上一次滚动位置
				isLoading: false // 是否正在加载
			}
		},
		computed: {
			currentChildClassList() {
				return this.classifyList || []
			},
			goodsList() {
				return this.currentChildClassList[this.currentLeftClassify]?.productList || []
			}
		},
		beforeMount() {
			// #ifdef MP-WEIXIN
			this.windowHeight = uni.getWindowInfo().windowHeight
			// #endif
			// #ifndef MP-WEIXIN
			this.windowHeight = uni.getSystemInfoSync().windowHeight
			// #endif
		},
		mounted() {
			setTimeout(() => {
				this.calculateItemPositions()
				this.init()
			}, 10)
		},
		methods: {
			init() {
				return new Promise((resolve, reject) => {
					let query = uni.createSelectorQuery().in(this);

					query.select(`.goods-list`).boundingClientRect(data => {
						// console.log(">>>data", data);

						// if(!data.height) {
						//     setTimeout(() => {
						//         // this.init();
						//     }, 10);
						//     return;
						// }
						this.goodsListHeight = data.height
						resolve();
					}).exec()
				})
			},
			onSelectClassify(index) {
				this.isCalculating = true;

				this.currentLeftClassify = index
				this.classIntoView = 'classItem' + index

				this.currentChildClassify = 0
				this.childClassIntoView = 'childClassItem0'

				this.goodsIntoView = 'goodsItem' + index
				this.scrollTop = this.oldScrollTop
				this.itemPositions = []

				this.checkClassTimer = setTimeout(() => {
					this.isCalculating = false;
				}, 1000);

				this.$nextTick(() => {
					this.scrollTop = 0; // 重置滚动位置为顶部，防止切换分类时出现滚动错位问题
					this.calculateItemPositions()
				})
			},
			onChildSelectClassify(index) {
				this.isCalculating = true;
				this.currentChildClassify = index
				this.childClassIntoView = 'childClassItem' + index;

				if (this.scrollTimer) clearTimeout(this.scrollTimer);
				if (this.checkClassTimer) clearTimeout(this.checkClassTimer);

				this.goodsIntoView = 'goodsItem' + index
				this.targetScrollTop = this.itemPositions[index].top;

				this.checkClassTimer = setTimeout(() => {
					this.isCalculating = false;
				}, 1000);
			},
			onScroll(e) {
				if (this.scrollTimer) clearTimeout(this.scrollTimer);
				this.saveScrollTop = e.detail.scrollTop;

				this.scrollTimer = setTimeout(() => {
					const scrollHeight = e.detail.scrollHeight;
					const scrollTop = e.detail.scrollTop;

					// 向上滚动
					if (e.detail.scrollTop < this.oldScrollTop) {
						this.isLoading = false;
					}
					this.oldScrollTop = e.detail.scrollTop;


					let currentIndex = 0
					// 如果是代码主动滚动且还未到达目标位置附近，不执行逻辑
					if (this.isCalculating && Math.abs(scrollTop - this.targetScrollTop) > 30) {
						return;
					}

					// 根据滚动位置和内容块位置信息，确定当前应该选中的分类
					this.itemPositions.forEach((item, index) => {
						// 防止索引超出分类数量
						if (currentIndex === this.currentChildClassList.length - 1) {
							return false
						}

						if (scrollTop >= item.height + this.threshold) {
							currentIndex = index + 1;
							this.currentChildClassify = currentIndex;
							this.childClassIntoView = 'childClassItem' + currentIndex;
						} else if (scrollTop === 0) {
							currentIndex = 0;
							this.currentChildClassify = currentIndex;
							this.childClassIntoView = 'childClassItem' + currentIndex;
						}
					});
				}, 10);
			},
			// 触顶
			onScrollToUpper() {
				// console.log(">>>", '触顶',this.isCalculating);

				if (this.currentLeftClassify !== 0 && !this.isCalculating) {
					this.isCalculating = true;
					this.currentLeftClassify -= 1;
					this.onSelectClassify(this.currentLeftClassify)

					setTimeout(() => {
						this.isCalculating = false;
					}, 600);
				}
			},
			// 触底
			onScrollToLower() {
				if (this.currentLeftClassify !== this.classifyList.length - 1 && !this.isCalculating) {
					if (!this.isLoading) {
						setTimeout(() => {
							this.isLoading = true;
						}, 300)
					} else {
						this.isCalculating = true;
						this.currentLeftClassify += 1;
						this.onSelectClassify(this.currentLeftClassify)

						setTimeout(() => {
							this.isCalculating = false;
						}, 1000);
					}
				}
			},
			onClickGoods(item, index) {
				this.$emit('clickGoods', item, index)
			},
			calculateItemPositions() {
				const query = uni.createSelectorQuery().in(this);

				// if (this.currentChildClassList.length === 0) {
				// 	return false
				// }
				const selectors = this.currentChildClassList.map((_, index) => `#goodsItem${index}`);
				// 并行获取所有内容块的位置信息
				Promise.all(selectors.map(selector => {
					return new Promise(resolve => {
						query.select(selector).boundingClientRect(resolve).exec();
					});
				})).then(results => {
					// console.log(">>>", results);

					this.itemPositions = results.reduce((acc, current, index) => {
						// 获取当前元素的height值
						const currentHeight = current.height || 0;
						const currentTop = current.top || 0;
						// 计算当前索引及之前所有height的累加和
						const sumHeight = (acc[index - 1]?.height || 0) + currentHeight;
						const sumTop = (acc[index - 1]?.top || 0) + currentTop;
						// 推送到新数组的是包含height属性的对象
						acc.push({
							height: sumHeight,
							top: sumTop
						});
					console.log(acc)
						return acc;
					}, []);
				}).catch(() => {

				});
			},
			cumulativeSum(arr) {
				return arr.reduce((acc, current, index) => {
					const sum = (acc[index - 1] || 0) + current;
					acc.push(sum);
					return acc;
				}, []);
			}
		}
	}
</script>

<style scoped>
	.classify {
		display: flex;
	}

	.left-main {
		width: 180rpx;
		height: 100%;
		background-color: #f5f5f5;
	}

	.class-item {
		width: 100%;
		height: 100rpx;
		line-height: 100rpx;
		padding-left: 40rpx;
		color: #666;
		text-overflow: ellipsis;
		overflow: hidden;
		white-space: nowrap;
	}

	.class-item-active {
		color: #000;
		font-weight: 600;
		position: relative;
		transition: 0.3;
	}

	.class-item-active::after {
		content: '';
		position: absolute;
		left: 0;
		top: 50%;
		margin-top: -20rpx;
		width: 8rpx;
		height: 40rpx;
		background-color: #00BEFF;
	}


	.right-main {
		width: 500rpx;
		padding: 20rpx 20rpx;
		flex: 1;
	}

	.child-class-main {
		height: 80rpx;
		border-bottom: 1rpx solid #E5E5E5;
	}

	.child-class-box {
		width: 100%;
		display: flex;
		align-items: center;
	}

	.child-class-item {
		margin-right: 20rpx;
		padding: 6rpx 15rpx;
		font-size: 28rpx;
		color: #666;
	}

	.child-class-item:last-child {
		margin-right: 0;
	}

	.child-class-item-active {
		color: #000;
		background-color: #F5F5F5;
		border-radius: 8rpx;
	}

	.goods-list {
		margin-top: 20rpx;
		height: calc(100% - 100rpx);
	}

	.child-item {
		padding-bottom: 64rpx;
	}

	/* .child-item:last-child {
    margin-bottom: 0;
} */

	.title {
		margin-bottom: 16rpx;
	}

	.goods-item {
		width: 100%;
		padding: 20rpx;
		background-color: #F5F5F5;
		border-radius: 8rpx;
		display: flex;
		align-items: center;
		margin-bottom: 24rpx;
	}

	.goods-item:last-child {
		margin-bottom: 0;
	}

	.goods-img {
		width: 100rpx;
		height: 100rpx;
		margin-right: 20rpx;
	}

	.goods-name {
		flex: 1;
		font-size: 28rpx;
		color: #666;
		text-overflow: ellipsis;
		overflow: hidden;
		white-space: nowrap;
	}

	.loading-tip {
		text-align: center;
		height: 150rpx;
		color: #999;
	}


	/* 隐藏滚动条 */
	::-webkit-scrollbar {
		width: 0;
		display: none;
	}
</style>